package ute.mvc.controller.portal.lecturer;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import ute.mvc.dto.ClassDTO;
import ute.mvc.dto.QuestionDTO;
import ute.mvc.model.MyClass;
import ute.mvc.model.OpenCourse_Subject;
import ute.mvc.model.Question;
import ute.mvc.model.TestAndQuizz;
import ute.mvc.model.TestPart;
import ute.mvc.model.User;
import ute.mvc.service.Course_SubjectService;
import ute.mvc.service.OpenCourseService;
import ute.mvc.service.QuestionService;
import ute.mvc.service.TestAndQuizzService;
import ute.mvc.service.TestPartService;
import ute.mvc.service.UserService;
import ute.mvc.util.IdUtil;
import ute.mvc.util.JsonObject;

@Controller
@RequestMapping(value = "/lecturer/{lecturerId}/{openCourseId}/{subjectId}/test")
public class TestAndQuizzController {

	@Autowired
	TestAndQuizzService testService;
	@Autowired
	OpenCourseService openCourseService;
	@Autowired
	Course_SubjectService courseSubjectService;
	@Autowired
	UserService userService;
	@Autowired
	TestPartService partService;
	@Autowired
	QuestionService questionService;

	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String getTestList(@PathVariable String openCourseId,
			@PathVariable String subjectId, Model model) {

		System.out.println("List Test: ");
		model.addAttribute("url", "lecturer/2/" + openCourseId + "/"
				+ subjectId);
		return "lecturer_test_list";
	}

	/**
	 * get Add Test View
	 * 
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/add", method = RequestMethod.GET)
	public String getAddTest(Model model) {

		TestAndQuizz test = new TestAndQuizz();
		model.addAttribute("test", test);
		return "lecturer_test_add";
	}

	/**
	 * Add Test OK
	 * 
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/add", method = RequestMethod.POST)
	public String addTest(@PathVariable int lecturerId,
			@PathVariable String openCourseId, @PathVariable String subjectId,
			@Valid @ModelAttribute("test") TestAndQuizz test,
			BindingResult result, Model model) {

		if (result.hasErrors())
			return "lecturer_test_add";
		if (test.getEndDay().compareTo(test.getStartDay()) <= 0) {
			result.rejectValue("endDay", "wrongendate");
			return "lecturer_test_add";
		}

		String id = openCourseId + "_" + subjectId;
		OpenCourse_Subject subject = courseSubjectService.getCourse_Subject(id);
		User lecturer = userService.getUserById(lecturerId);
		String maxId = testService.getMaxIdInOpenCourseSubject(subject);
		String newId = IdUtil.getNewTestIdInOpenCourseSubject(maxId);

		test.setTestAndQuizzID(id + "_" + newId);
		test.setOpenCourse_Subject(subject);
		test.setLecturer(lecturer);
		testService.addTestAndQuizz(test);
		return "redirect:info/" + id + "_" + newId;
	}

	@RequestMapping(value = "/info/{testId}", method = RequestMethod.GET)
	public String getTestInfo(@PathVariable String testId,
			@PathVariable String openCourseId, @PathVariable String subjectId,
			Model model) {
		model.addAttribute("url", "portal/2/" + openCourseId + "/" + subjectId);
		System.out.println("Information: " + testId);

		TestAndQuizz test = testService.getTestAndQuizz(testId);
		model.addAttribute("test", test);
		return "lecturer_test_info";
	}

	@RequestMapping(value = "/edit/{testId}", method = RequestMethod.GET)
	public String getEditTest(@PathVariable String testId,
			@PathVariable String openCourseId, @PathVariable String subjectId,
			Model model) {
		model.addAttribute("url", "portal/2/" + openCourseId + "/" + subjectId);
		System.out.println("Get Edit Test");
		TestAndQuizz test = testService.getTestAndQuizz(testId);
		model.addAttribute("test", test);
		System.out.println(test.getStartDay());
		System.out.println(test.getEndDay());
		return "lecturer_test_edit";
	}

	@RequestMapping(value = "/edit/{testId}", method = RequestMethod.POST)
	public String editTest(@Valid @ModelAttribute("test") TestAndQuizz test,
			BindingResult result, @PathVariable String testId,
			@PathVariable String openCourseId, @PathVariable String subjectId,
			Model model) {
		if (result.hasErrors())
			return "lecturer_test_edit";
		TestAndQuizz oldTest = testService.getTestAndQuizz(testId);
		// model.addAttribute("url", "portal/2/" + openCourseId + "/" +
		// subjectId);

		test.setLecturer(oldTest.getLecturer());
		test.setListTestPart(oldTest.getListTestPart());
		test.setOpenCourse_Subject(oldTest.getOpenCourse_Subject());
		testService.updateTestAndQuizz(test);

		return "redirect:../info/" + testId;
	}

	@RequestMapping(value = "/detail/{testId}", method = RequestMethod.GET)
	public String getTestDetail(@PathVariable String testId,
			@PathVariable String openCourseId, @PathVariable String subjectId,
			Model model) {
		System.out.println("Test Detail: " + testId);
		// List all test, test part... like sakai
		// Get Test
		TestAndQuizz test = testService.getTestAndQuizz(testId);
		// Get TestPart
		List<TestPart> lstPart = partService.getTestPartByTest(test);
		List<Question> lstQuestion;
		List<QuestionDTO> lstQuestionDTO;
		for (TestPart p : lstPart) {
			if (p.getQuestionPool() == null) {
				lstQuestion = questionService.getQuestionInPart(p);
				lstQuestionDTO = new ArrayList<QuestionDTO>();
				for (Question q : lstQuestion) {
					lstQuestionDTO.add(new QuestionDTO(q));
				}
				p.setListQuestionDTO(lstQuestionDTO);
			}
		}
		test.setListTestPart(lstPart);
		System.out.println(lstPart.size());
		model.addAttribute("test", test);
		// Get Question in TestPart
		return "lecturer_test_detail";
	}

	@RequestMapping(value = "/delete/{testId}", method = RequestMethod.GET)
	@ResponseBody
	public String deleteTest(@PathVariable String testId,
			@PathVariable String openCourseId, @PathVariable String subjectId,
			Model model) {
		TestAndQuizz test = testService.getTestAndQuizz(testId);
		testService.deleteTestAndQuizz(test);

		return "OK";
	}

	/**
	 * JSON method
	 */

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping(value = "/listJSON")
	@ResponseBody
	public JsonObject getTestList(@PathVariable int lecturerId,
			@PathVariable String openCourseId, @PathVariable String subjectId) {
		// Complete
		String openCourseSubject = openCourseId + "_" + subjectId;

		OpenCourse_Subject subject = courseSubjectService
				.getCourse_Subject(openCourseSubject);
		User lecturer = userService.getUserById(lecturerId);
		List<TestAndQuizz> list = testService.getTestBySubject(subject,
				lecturer);

		JsonObject testJson = new JsonObject();
		testJson.setAaData(list);
		testJson.setiTotalRecords(list.size());
		testJson.setiTotalDisplayRecords(list.size());
		testJson.setsEcho(1);
		return testJson;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping(value = "/info/{testId}/classJSON")
	@ResponseBody
	public JsonObject getClassList(@PathVariable String testId,
			@PathVariable int lecturerId, @PathVariable String openCourseId,
			@PathVariable String subjectId) {
		// In-Complete
		List<MyClass> all = openCourseService.getAllClass(openCourseId);
		List<MyClass> aList = new ArrayList<MyClass>();
		aList.addAll(testService.getClassByTestId(testId));
		List<ClassDTO> classList = new ArrayList<ClassDTO>();
		boolean flag = false;
		for (int i = 0; i < all.size(); i++) {
			for (int j = 0; j < aList.size(); j++) {
				if (all.get(i).getClassId().equals(aList.get(j).getClassId())) {
					flag = true;
				}
			}
			if(flag == true){
				classList.add(new ClassDTO(all.get(i), true));
			}else{
				classList.add(new ClassDTO(all.get(i), false));
			}
			flag = false;
		}

		JsonObject testJson = new JsonObject();
		testJson.setAaData(classList);
		testJson.setiTotalRecords(classList.size());
		testJson.setiTotalDisplayRecords(classList.size());
		testJson.setsEcho(1);
		return testJson;
	}

	@RequestMapping(value = "/info/{testId}/update", method = RequestMethod.POST)
	@ResponseBody
	public String updateClassTest(@PathVariable String openCourseId,
			@PathVariable String testId, @RequestBody String listClass) {
		testService.updateClasses(testId, listClass);
		return "OK";
	}

}
